﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ForumServer.Forum
{
    public class User : MarshalByRefObject, IUser
    {
        protected string _username;
        protected string _password;//encrypted
        protected string _eMail;
        protected string _phoneNumber;
        protected string _firstName;
        protected string _lastName;
        protected List<Thread> _threadsPosted;
        protected List<Post> _posts;
        protected List<User> _friends;
        protected List<User> _requests;

        /// <summary>
        /// Default constructor
        /// </summary>
        public User()
        {
            _threadsPosted = new List<Thread>();
            _posts = new List<Post>();
            _friends = new List<User>();
            _requests = new List<User>();
        }

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="tName">user name</param>
        /// <param name="tPass">masked password</param>
        /// <param name="tMail">eMail</param>
        /// <param name="tNumber">phone number</param>
        /// <param name="tFirstName">first name</param>
        /// <param name="tLastName">last name</param>
        public User(string tName, string tPass, string tMail, string tNumber, string tFirstName, string tLastName){

            _username = tName;
            _password = tPass;
            _eMail = tMail;
            _phoneNumber = tNumber;
            _firstName = tFirstName;
            _lastName = tLastName;
            _threadsPosted = new List<Thread>();
            _posts = new List<Post>();
            _friends = new List<User>();
            _requests = new List<User>();
        }

        public string Username { get { return _username; } set{_username  = value; } }
        public string Password { get { return _password; } set{_password  = value; } }
        public string EMail { get { return _eMail; } set{_eMail  = value; } }
        public string FirstName { get { return _firstName; } set{_firstName  = value; } }
        public string LastName { get { return _lastName; } set{_lastName  = value; } }
        public List<Thread> ThreadsPosted { get { return _threadsPosted; } set{_threadsPosted  = value; }  }
        public List<Post> Posts { get { return _posts; } set { _posts = value; } }
        public List<User> Friends { get { return _friends; } set { _friends = value; } }
        public List<User> Requests { get { return _requests; } set { _requests = value; } }

        /// <summary>
        /// User add new Thread to Forum. update _threadsPosted with new Thread
        /// </summary>
        /// <param name="header">Thread header</param>
        /// <param name="body">Thread body</param>
        public void addThread(string header, string body)
        {
            Thread tThread = new Thread(header,body, this);//update constructor - add date time

            _threadsPosted.Add(tThread);
        }
        
        /// <summary>
        /// User replies a Thread curThread. update _posts with new post
        /// </summary>
        /// <param name="curThread">Current thread to reply in</param>
        /// <param name="header">Post header</param>
        /// <param name="body">Post body</param>
        public void replyPost(Thread curThread, string header, string body)
        {
            Post tPost = new Post(header ,body ,DateTime.UtcNow, this);
            _posts.Add(tPost);
        }

        /// <summary>
        /// User edit post.update _posts with edited post
        /// </summary>
        /// <param name="post">post to edit</param>
        /// <param name="header">Post header</param>
        /// <param name="body">Post body</param>
        public void editPost(Post post, string header, string body)
        {
            int index = _posts.IndexOf(post);
            post.Content = body;
            post.Header = header ;
            _posts.Insert(index, post);
        }

        /// <summary>
        /// User deletes post.
        /// </summary>
        /// <param name="post">post to delete</param>
        public void deletePost(Post post)
        {
            _posts.Remove(post);
        }

        /// <summary>
        /// add friend to list.s
        /// </summary>
        /// <param name="friend">friend to add</param>
        public void addFriend(User friend)
        {
            _friends.Add(friend);
            friend._friends.Add(this);//It takes two to tango! (Chezi)
        }

        /// <summary>
        /// Remove friend from friends list.
        /// </summary>
        /// <param name="friend">friend to remove</param>
        public void removeFriend(User friend)
        {
            _friends.Remove(friend);
            friend._friends.Remove(this);//It takes two to tango! (Chezi)
        }

        //same as add. usfull???
        public void confirmRequest(User friend)
        {
            this.addFriend(friend);//delegation to addFriend method
        }


        /// <summary>
        /// Reject request. delete friend from _requests
        /// </summary>
        /// <param name="friend">friend to reject</param>
        public void rejectRequest(User friend)
        {
            _requests.Remove(friend);
        }



        public void hello(string message)
        {
            Console.WriteLine("received " + message);
        }
        /// <summary>
        /// this method returns the users friends list.
        /// </summary>
        /// <returns></returns>
        public string getFriendslist()
        {
            string ans = "";
            if (this._friends.Count > 0)
            {
                for (int i = 0; i < this._friends.Count; i++)
                {
                    ans += this._friends[i].ToString() + "\n";
                }
            }
            else
                ans = "User has no friends!\n";
            return ans;
        }

        public override String ToString()
        {
            return _username;
        }
    }
}
